﻿using UnityEngine;

// 外观 中介者模式
// 对状态管理来说，外观模式提供了接口,可以让状态管理更为稳定和集中，更易于维护
// 对游戏各个子系统,中介者可以起到一个协调的作用,让各个子系统之间相互独立，降低耦合度

public class GameFacade
{
    private static readonly GameFacade _instance = new GameFacade();

    // 子系统实例
    private ArchievementSystem mArchievementSystem;
    private CampSystem mCampSystem;
    private CharacterSystem mCharacterSystem;
    private EnergySystem mEnergySystem;
    private GameEventSystem mGameEventSystem;
    private StageSystem mStageSystem;
    private GamePauseUI mGamePauseUI;
    private CampInfoUI mCampInfoUI;
    private GameStateInfoUI mGameStateInfoUI;
    private SoldierInfoUI mSoldierInfoUI;

    private bool misGameOver = false;

    private GameFacade() { }

    public static GameFacade Instance { get { return _instance; } }

    // 子系统之间的通信交互
    public void Init()
    {
        mArchievementSystem = new ArchievementSystem();
        mCampSystem = new CampSystem();
        mCharacterSystem = new CharacterSystem();
        mEnergySystem = new EnergySystem();
        mGameEventSystem = new GameEventSystem();
        mStageSystem = new StageSystem();
        mCampInfoUI = new CampInfoUI();
        mGamePauseUI = new GamePauseUI();
        mGameStateInfoUI = new GameStateInfoUI();
        mSoldierInfoUI = new SoldierInfoUI();
        mArchievementSystem.Init();
        mCampSystem.Init();
        mCharacterSystem.Init();
        mEnergySystem.Init();
        mGameEventSystem.Init();
        mStageSystem.Init();
        mCampInfoUI.Init();
        mGamePauseUI.Init();
        mGameStateInfoUI.Init();
        mSoldierInfoUI.Init();

        LoadMemento();
    }

    public void Update()
    {
        mArchievementSystem.Update();
        mCampSystem.Update();
        mCharacterSystem.Update();
        mEnergySystem.Update();
        mGameEventSystem.Update();
        mStageSystem.Update();
        mCampInfoUI.Update();
        mGamePauseUI.Update();
        mGameStateInfoUI.Update();
        mSoldierInfoUI.Update();
    }

    public void Release()
    {
        mArchievementSystem.Release();
        mCampSystem.Release();
        mCharacterSystem.Release();
        mEnergySystem.Release();
        mGameEventSystem.Release();
        mStageSystem.Release();
        mCampInfoUI.Release();
        mGamePauseUI.Release();
        mGameStateInfoUI.Release();
        mSoldierInfoUI.Release();

        CreateMemento();

    }

    // mCampInfoUI 显示兵营UI面板；当兵营被点击的时候
    public void ShowCampInfo(ICamp camp) { mCampInfoUI.ShowCampInfo(camp); }


    public void AddEnemy(IEnemy enemy) { mCharacterSystem.AddEnemy(enemy); }

    // 能否使用能量
    public bool TakeEnergy(int value)
    {
        return mEnergySystem.TakeEnergy(value);
    }
    public void RecycleEnergy(int value)
    {
        mEnergySystem.RecycleEnergy(value);
    }

    public void ShowMsg(string msg)
    {
        mGameStateInfoUI.ShowMsg(msg);
    }
    // 更新能量条
    public void UpdateEnergySlider(int nowEnergy, int maxEnergy)
    {
        mGameStateInfoUI.UpdateEnergySlider(nowEnergy, maxEnergy);
    }

    public Vector3 GetEnemyTargetPosition()
    {
        return mStageSystem.targetPosition;
    }

    public void RegisterObserver(GameEventType eventType, IGameEventObserver observer)
    {
        mGameEventSystem.RegisterObserver(eventType,observer);
    }

    public void RemoveObserver(GameEventType eventType, IGameEventObserver observer){
        mGameEventSystem.RemoveObserver(eventType,observer);
    }

    public void NotifySubject(GameEventType eventType)
    {
        mGameEventSystem.NotifySubject(eventType);
    }

    private void LoadMemento()
    {
        AchievementMemento memento = new AchievementMemento();
        memento.LoadData();
        mArchievementSystem.SetMemento(memento);
    }

    private void CreateMemento()
    {
        AchievementMemento memento= mArchievementSystem.CreateMemento();
        // 对象可以替换,但数据已经保存通过 PlayerPrefs.GetInt 等方法 保存到本地
        memento.SaveData();
    }

    public void RunVisitor(ICharacterVisitor visitor)
    {
        mCharacterSystem.RunVisitor(visitor);
    }

    public void RemoveEnemy(IEnemy enemy)
    {
        mCharacterSystem.RemoveEnemey(enemy);
    }

    public void AddSoldier(ISoldier soldier)
    {
        mCharacterSystem.AddSoldier(soldier);
    }
}